package edu.gatech.cs2340.bytebankers.presenter;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import edu.gatech.cs2340.bytebankers.notifications.*;
import java.util.HashMap;
import java.util.List;

import javax.swing.*;
import javax.print.DocFlavor.URL;


import com.sun.org.apache.bcel.internal.generic.NEW;

import edu.gatech.cs2340.bytebankers.model.*;
import edu.gatech.cs2340.bytebankers.model.profession.*;
import edu.gatech.cs2340.bytebankers.config.InitialStartUpValues;
import edu.gatech.cs2340.bytebankers.game.GameManager;
import edu.gatech.cs2340.bytebankers.view.IStartupView;

public class StartupPresenter extends Notifier implements IStartupPresenter {
	Journey journey;
	IStartupView startupView;
	
	/**
	 * Constructor
	 * @param journey The journey which represents the data model.
	 */
	public StartupPresenter(Journey journey) {
		this.journey = journey;		
	}

	/**
	 * Sets the view that this presenter will interact with.
	 * @param startupView The view to use.
	 */
	public void setView(IStartupView startupView) {
		this.startupView = startupView;
		
		HashMap<String, String> professions = new HashMap<String, String>(InitialStartUpValues.NUM_OF_PROFESSIONS);
		
		
		// Need to get the following code working. This will automatically add
		// all professions the system finds. Removes the need for the hard coded
		// string values that follow.
		/*
		try {
			ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
	        assert classLoader != null;
	        String packageName = "edu.gatech.cs2340.bytebankers.model.profession"; 
	        String path = packageName.replace('.', '/');
	        Enumeration<java.net.URL> resources = classLoader.getResources(path);
	        List<File> dirs = new ArrayList<File>();
	        while (resources.hasMoreElements()) {
	            java.net.URL resource = resources.nextElement();
	            if(!resource.getFile().startsWith("IProfession")) {
	            	professions.put(resource.getFile(), packageName + "." + resource.getFile());
	            }
	        }
		} catch (Exception e) {
			System.out.print("EXCEPTION: " + e.getMessage());
		}
		
		*/
		
		// Build a hash map of professions, the key being the name of the profession
		// and the value being the full class name.
		professions.put("Banker", "edu.gatech.cs2340.bytebankers.model.profession.Banker");
		professions.put("Carpenter", "edu.gatech.cs2340.bytebankers.model.profession.Carpenter");
		professions.put("Farmer", "edu.gatech.cs2340.bytebankers.model.profession.Farmer");
		
		startupView.setProfessions(professions);
	}

	/**
	 * Called when the user saves the form. Main logic goes here.
	 */
	public void onSaveForm() {
		try{
			
			IProfession profession;
			
			// store the values from the view that the user entered.
			String leaderName = startupView.getLeaderName();
			List<String> playerNameStrings = startupView.getPlayerNames();
			
			// using introspection, get a reference to the class related
			// to the chosen profession and instantiate it.
			Class professionClass = Class.forName(startupView.getProfession());
			profession = (IProfession)professionClass.newInstance();
			
			// create the leader and specify his/her properties
			Leader leader = new Leader();
			leader.setName(leaderName);
			leader.setProfession(profession);
			leader.setHealth(InitialStartUpValues.START_HEALTH);
			leader.setsickStatus("good");
			
			Wagon wagon = new Wagon();
			journey.setWagon(wagon);
			
			// add the objects to the journey
			journey.addPlayer(leader);
			journey.setLeader(leader);
			journey.setPace(startupView.getPace());
			journey.setRationRate(startupView.getRationRate());
			
			// loop through players and create them and add to journey
			for(int i = 0; i < playerNameStrings.size(); i++) {
				Player player = new Player();
				player.setName(playerNameStrings.get(i));
				player.setHealth(InitialStartUpValues.START_HEALTH);
				player.setsickStatus("good");
				journey.addPlayer(player);	
			}
		}
		catch (Exception e) {
			e.printStackTrace();
		}	
		
		sendNotification(GameEvents.STARTUP_FINISHED);
	}

	@Override
	public void onLoadGameClick() {
		try {
			//Create a file chooser
			final JFileChooser fc = new JFileChooser();
			
			int returnVal = fc.showOpenDialog(startupView.getMainPanel());
			
			if(returnVal != JFileChooser.APPROVE_OPTION) return;
			
			// Read from disk using FileInputStream
			FileInputStream f_in = new 
				FileInputStream(fc.getSelectedFile());

			// Read object using ObjectInputStream
			ObjectInputStream obj_in = 
				new ObjectInputStream (f_in);

			// Read an object
			Object obj = obj_in.readObject();

			if (obj instanceof Journey)
			{
				// Cast object to a Journey
				journey = (Journey) obj;
			}
			
			GameManager.setJourney(journey);
			sendNotification(GameEvents.GAME_LOADED);

		} catch (ClassNotFoundException e) {
		} catch (IOException e) {
		}
		
	}
	

	
}
